﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Infrastructure.Aspect.Services.XmlDataQueries;
using Skynet.BusinessEntities;
using System.Transactions;
using System.ServiceModel.Activation;
using System.ServiceModel;
using System.Threading;
using System.Security.Principal;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF;


namespace Skynet.BusinessLogic.BusinessComponents
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [ExceptionShielding("ServiceInterfacePolicy")]
    public partial class BCExamQueries : IBCExamQueries
    {
        [Dependency]
        public DataAccess.IExamCategoryRepository ExamCategoryRepository { protected get; set; }

        [Dependency]
        public DataAccess.IExamRepository ExamRepository { get; set; }

        [Dependency]
        public DataAccess.IQuestionRepository QuestionRepository { get; set; }

        [Dependency]
        public DataAccess.IAlternativeRepository AlternativeRepository { get; set; }

        [Dependency]
        public DataAccess.IExamByCustomerRepository ExamByCustomerRepository { get; set; }

        [Dependency]
        public DataAccess.IAlternativeExpEvaluationRepository AlternativeExpEvaluationRepository { get; set; }

        [Dependency]
        public IXmlDataQueriesService XmlDataQueriesService { get; set; }


        
        public IEnumerable<ExamCategory> SearchExamCategories(SearchExamCategoriesOptions options = SearchExamCategoriesOptions.GetAll, Guid? Id = null)
        {

            var ent = new Infrastructure.Aspect.Transactions.ObjectResourceManager<ExamCategory>(); 
            ent.Target = new ExamCategory(){Id = Guid.NewGuid(), Title  = "test"};
            TransactionScope scope = new TransactionScope();

            Transaction.Current.EnlistVolatile(ent, EnlistmentOptions.None);

            ent.Target.Title = "nuevo ttest";

            scope.Complete();

            scope.Dispose();

            IEnumerable<ExamCategory> result = null;
            switch (options)
            {
                case SearchExamCategoriesOptions.GetAll:
                    result = this.ExamCategoryRepository.GetAll();
                    break;
                case SearchExamCategoriesOptions.GetOne:
                    var tmp = this.ExamCategoryRepository.GetOne(Id);
                    if (tmp != null)
                        result = new List<ExamCategory>() { tmp };
                    break;
                default:
                    break;
            }
            return result;
        }

        
        public IEnumerable<Exam> SearchExams(ExamSearchOptions options = ExamSearchOptions.GetAll, Guid? id = null, Guid? CustomerId = null, Guid? CategoryId = null)
        {
            IEnumerable<Exam> result = null;
            switch (options)
            {
                case ExamSearchOptions.GetAll:
                    result = this.ExamRepository.GetAll();
                    break;
                case ExamSearchOptions.GetOne:
                    var tmp = this.ExamRepository.GetOne(id);
                    result = new List<Exam>() { tmp };
                    break;
                case ExamSearchOptions.GetByCustomerId:
                    result = this.ExamRepository.GetByCustomerId(CustomerId.Value);
                    break;
                case ExamSearchOptions.GetByCustomerIdCategoryId:
                    result = this.ExamRepository.GetByCustomerIdCategoryId(CategoryId.Value, CustomerId.Value);
                    break;
                case ExamSearchOptions.GetDesignByCustomerIdCategoryId:
                    result = this.ExamRepository.GetDesignByCustomerIdCategoryId(CategoryId.Value, CustomerId.Value);
                    break;
                default:
                    break;
            }
            return result;
        }

        
        public IEnumerable<ExamByCustomer> SearchExamByCustomer(ExamByCustomerSearchOptions options = ExamByCustomerSearchOptions.GetByCustomerId, Guid? CustomerId = null, Guid? ExamByCustomerId = null)
        {
            IEnumerable<ExamByCustomer> result = new List<ExamByCustomer>();
            switch (options)
            {
                case ExamByCustomerSearchOptions.GetByExamByCustomerId:
                    var restmp = new List<ExamByCustomer>();
                    restmp.Add(this.ExamByCustomerRepository.GetOne(ExamByCustomerId));
                    result = restmp;
                    break;
                case ExamByCustomerSearchOptions.GetByCustomerId:
                    result = this.ExamByCustomerRepository.GetExamByCustomer(CustomerId.GetValueOrDefault());
                    break;
                case ExamByCustomerSearchOptions.RuntimeByCustomerId:
                    result = this.ExamByCustomerRepository.GetRuntimeByCustomer(CustomerId.GetValueOrDefault());
                    break;
                case ExamByCustomerSearchOptions.RuntimeActiveByCustomerId:
                    var exams = this.ExamByCustomerRepository.GetRuntimeByCustomer(CustomerId.GetValueOrDefault());
                    result = (from c in exams where c.Status == (short)BusinessEntities.ExamActivationStatus.Active && c.ValidFrom <= DateTime.Now && c.ValidTo >= DateTime.Now select c).ToList();
                    break;
                case ExamByCustomerSearchOptions.RuntimeByCustomerExamId:
                    var exam = this.ExamByCustomerRepository.GetRuntimeByCustomerExamId(ExamByCustomerId.Value);
                    ((List<ExamByCustomer>)result).Add(exam);
                    break;
                case ExamByCustomerSearchOptions.RuntimeRunningByCustomerId:
                    var runningexams = this.ExamByCustomerRepository.GetRuntimeByCustomer(CustomerId.GetValueOrDefault());
                    result = (from c in runningexams where c.Status == (short)BusinessEntities.ExamActivationStatus.Inprogress && c.ValidFrom <= DateTime.Now && c.ValidTo >= DateTime.Now select c).ToList();
                    break;
                case ExamByCustomerSearchOptions.RuntimeCompleteByCustomerId:
                    var completeexams = this.ExamByCustomerRepository.GetRuntimeByCustomer(CustomerId.GetValueOrDefault());
                    result = (from c in completeexams where c.Status == (short)BusinessEntities.ExamActivationStatus.Finish select c).ToList();
                    break;
                default:
                    break;
            }
            return result;
        }

        
        public string QueryExams(QueryExamOptions Options = QueryExamOptions.DesignListView, Guid? CategoryId = null, Guid? CustomerId = null)
        {
            string result = String.Empty;
            switch (Options)
            {
                case QueryExamOptions.DesignListView:
                    result = XmlDataQueriesService.executeprocedure(Constants.OperationsNames.Exams.DesignExamsView, CategoryId, CustomerId);
                    break;
                default:
                    break;
            }
            return result;
        }
        
        public string ValidationSystem()
        {
            StringBuilder sb = new StringBuilder();
            try
            {

                sb.AppendLine("Thread Identity ");
                sb.AppendLine(Thread.CurrentPrincipal.Identity.Name);
                sb.AppendLine(Thread.CurrentPrincipal.Identity.AuthenticationType.ToString());
                sb.AppendLine(WindowsIdentity.GetCurrent().Name);
                sb.AppendLine(WindowsIdentity.GetCurrent().AuthenticationType.ToString());
            }
            catch (Exception ex)
            {
                sb.AppendLine(ex.Message);
            }
            try
            {

                sb.AppendLine("Windows");                
                sb.AppendLine(WindowsIdentity.GetCurrent().Name);
                sb.AppendLine(WindowsIdentity.GetCurrent().AuthenticationType.ToString());
            }
            catch (Exception ex)
            {
                sb.AppendLine(ex.Message);
            }
            try
            {

                sb.AppendLine("WCF Primary");
                sb.AppendLine(OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name);
                sb.AppendLine(OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.AuthenticationType);
            }
            catch (Exception ex)
            {
                sb.AppendLine(ex.Message);
            }
            try
            {

                sb.AppendLine("WCF Windows");
                sb.AppendLine(OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name);
                sb.AppendLine(OperationContext.Current.ServiceSecurityContext.WindowsIdentity.AuthenticationType);
            }
            catch (Exception ex)
            {
                sb.AppendLine(ex.Message);
            }   
            return sb.ToString();
           // this.ExamByCustomerRepository.ValidationStatesSystem();
        }

        
        public double FindExamByCustomer(FindExamByCustomerOptions options = FindExamByCustomerOptions.ActiveExams, Guid? CustomerId = null)
        {
            ValidationSystem();
            double result = 0;
            switch (options)
            {
                case FindExamByCustomerOptions.ActiveExams:
                    result = this.ExamByCustomerRepository.CountActiveExams(CustomerId.Value);
                    break;
                case FindExamByCustomerOptions.RunningExams:
                    result = this.ExamByCustomerRepository.CountRunningExams(CustomerId.Value);
                    break;
                case FindExamByCustomerOptions.CompleteExams:
                    result = this.ExamByCustomerRepository.CountCompleteExams(CustomerId.Value);
                    break;
                default:
                    break;
            }
            return result;
        }

        
        public IEnumerable<BaseAlternative> SearchAlternatives(SearchAlternativesOptions options = SearchAlternativesOptions.DesignOne, Guid? AlternativeId = null, Guid? QuestionId = null)
        {
            List<BaseAlternative> result = new List<BaseAlternative>();
            switch (options)
            {
                case SearchAlternativesOptions.DesignOne:
                    result.Add(this.AlternativeRepository.DesignAlternative(AlternativeId.Value));
                    break;
                case SearchAlternativesOptions.DesignListByQuestionId:
                    var res = this.AlternativeRepository.DesignAlternativesByQuestionId(QuestionId.Value);
                    if (res != null)
                        result.AddRange(res);
                    break;
                default:
                    break;
            }
            return result;
        }

        
        public void LoadQuestion(LoadQuestionOptions options, ref BaseQuestion Question)
        {
            switch (options)
            {
                case LoadQuestionOptions.LoadRuntimeQuestion:
                    this.QuestionRepository.LoadRuntimeQuestion(ref Question);
                    break;
                case LoadQuestionOptions.LoadDesignAlternatives:
                    Question.Alternatives = this.AlternativeRepository.DesignAlternativesByQuestionId(Question.Id);
                    break;
                case LoadQuestionOptions.LoadRuntimeAlternatives:
                    Question.Alternatives = this.AlternativeRepository.RuntimeAlternativesByQuestionId(Question.CustomerQuestionId);
                    break;
                default:
                    break;
            }
        }

        
        public void LoadAlternative(LoadAlternativeOptions options, ref BaseAlternative Alternative)
        {
            switch (options)
            {
                case LoadAlternativeOptions.LoadCustomerAnswer:
                    this.AlternativeRepository.LoadCustomerAnswer(ref Alternative);
                    break;
                case LoadAlternativeOptions.LoadDesignAlternative:
                    this.AlternativeRepository.LoadDesignAlternative(ref Alternative);
                    break;
                default:
                    break;
            }
        }

    }
}
